#include <54func.h>
// 1.0
// 用于客户端向服务区接收数据

//int recvFile(int sockfd)
//{
//    char filename[4096] = {0};
//    recv(sockfd,filename,sizeof(filename),0);//读取传送的文件名
//    int fd = open(filename,O_RDWR|O_CREAT);//根据文件名，创建文件
//    ERROR_CHECK(fd,-1,"open");
//    char buf[1000] = {0};
//    ssize_t sret = recv(sockfd,buf,sizeof(buf),0); //从socket中读文件内容
//    write(sockfd,buf,sret);//把读取的文件内容写道文件内
//    return 0;
//}

// 2.0 小文件发送
//typedef struct train_s{
//    int length;
//    char data[1000];
//}train_t;
//int recvFile(int sockfd)
//{
//    char filename[4096] = {0};
//    train_t train;
//    //先收火车头，以知道火车车厢的实际长度
//    recv(sockfd,&train.length,sizeof(train.length),0);//火车头
//    recv(sockfd,train.data,train.length,0);//火车车厢
//    memcpy(filename,train.data,train.leingth);
//
//    int fd = open(filename,O_CREAT|O_RDWR,0666);
//    ERROR_CHECK(fd,-1,"open");
//    recv(sockfd,&train.length,sizeof(train.length),0);
//    recv(sockfd,train.data,train.length,0);
//    write(fd,train.data,train.length);
//    close(fd);
//    return 0;
//
//}

// 3.0 大文件发送
//typedef struct train_s{
//    int length;
//    char data[1000];
//}train_t;
//int recvFile(int sockfd)
//{
//    train_t train;
//    char filename[4096];
//    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
//    recv(sockfd,train.data,train.length,MSG_WAITALL);
//    memcpy(filename,train.data,train.length);
//
//    int fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);
//    while(1)
//    {
//        recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
//        if(train.length != 1000)
//        {
//            printf("train.length = %d\n",train.length);
//        }
//        if(train.length == 0)
//        {
//            break;
//        }
//        recv(sockfd,train.data,train.length,MSG_WAITALL);
//        write(fd,train.data,train.length);
//       // // 如果读取的火车头数据长度为0，则数据读完，
//       // if(sret == 0)
//       // {
//       //     break;
//       // }
//    }
//
//    close(fd);
//    return 0;
//}

// v4.0 进度条显示
typedef struct train_s{
    int length;
    char data[1000];
}train_t;
int recvFile(int sockfd)
{
    train_t train;
    char filename[4096];
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.data,train.length,MSG_WAITALL);
    memcpy(filename,train.data,train.length);

    // 接收文件长度
    off_t filesize;
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.data,train.length,MSG_WAITALL);
    memcpy(&filesize,train.data,train.length);
    printf("filesize = %ld\n",filesize);
    off_t cursize = 0;//off_t：表示文件的偏移量
    off_t lastsize = 0;// 上次printf的时候，文件的大小
    off_t slice = filesize/10000;// 若是前后两次文件大小打印的差距若是不到万分之一，则没有必要更新i
    
    int fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);
    while(1)
    {
        recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
        if(train.length != 1000)
        {
            printf("train.length = %d\n",train.length);
        }
        if(train.length == 0)
        {
            break;
        }
        cursize += train.length;
        recv(sockfd,train.data,train.length,MSG_WAITALL);
        write(fd,train.data,train.length);
       // // 如果读取的火车头数据长度为0，则数据读完，
       // if(sret == 0)
       // {
       //     break;
       // }
        if(cursize - lastsize > slice)
        {
            // 若是这次打印相较于上次打印差距超过百分之0.0001，则打印：w:w
            printf("%5.2lf%%\r",cursize*100.0/filesize);
            fflush(stdout);
            lastsize = cursize;
        }
    }
    printf("100%%\n");
    close(fd);
    return 0;
}

int main(int argc,char * argv[])
{
    // ./ client 192.168.187.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
    ERROR_CHECK(ret,-1,"connect");
    
    //接收文件,并且创建文件
    recvFile(sockfd);
    close(sockfd);
    return 0;
}
